package org.osomit.sacct.io.impl;

import org.osomit.sacct.io.iface.ServerReaderWriter;
import org.osomit.sacct.io.ReadException;
import org.osomit.sacct.io.WriteException;
import org.osomit.sacct.entity.Request;
import org.osomit.sacct.entity.SecureResponse;
import org.osomit.sacct.entity.SecureRequest;
import org.osomit.sacct.utils.ExceptionUtil;
import org.osomit.sacct.builder.RequestBuilder;
import org.osomit.sacct.builder.SecureRequestBuilder;
import org.stringtree.json.JSONReader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.IOException;

/**
 * @author Jian Fang (John.Jian.Fang@gmail.com)
 *
 * Date: Jun 28, 2009
 */
public class JSONServerReaderWriter implements ServerReaderWriter {
    
    private JSONReader jsreader = new JSONReader();
    private SecureRequestBuilder builder = new SecureRequestBuilder();

	private Log log = LogFactory.getLog(JSONServerReaderWriter.class);

    public SecureRequest read(BufferedReader reader) {
        try {
            String out = reader.readLine();
            if(out == null)
                return null;
            
            Object obj = jsreader.read(out);
            SecureRequest request = builder.build(obj);

            return request;
        } catch (IOException e) {
            log.error(ExceptionUtil.describeException(e));
            
            throw new ReadException("Error reading request " + e.getMessage());
        }
    }

    public void write(OutputStream outputStream, SecureResponse response) {
        try {
//          Make sure add EOL there, other the socket reader will hange there 
            String resp =  response.toJSON().toString() + "\n";
            // send the response
            outputStream.write(resp.getBytes());
            outputStream.flush();
        } catch (IOException e) {
            log.error(ExceptionUtil.describeException(e));

            throw new WriteException("Error writing request " + e.getMessage());

        }
    }
}
